package cn.edu.cug.cs.gtl.oi.inventor.demo;
import java.awt.BorderLayout;
import java.awt.Component;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;

import com.openinventor.inventor.SbBox2i32;
import com.openinventor.inventor.SbBox3f;
import com.openinventor.inventor.SbColor;
import com.openinventor.inventor.SbVec3i32;
import com.openinventor.inventor.SoPreferences;
import com.openinventor.inventor.devices.SoBufferObject;
import com.openinventor.inventor.devices.SoBufferObject.AccessModes;
import com.openinventor.inventor.devices.SoCpuBufferObject;
import com.openinventor.inventor.nodes.SoGradientBackground;
import com.openinventor.inventor.nodes.SoSeparator;
import com.openinventor.inventor.viewercomponents.awt.IViewerExaminer;
import com.openinventor.ldm.nodes.SoDataSet.DataTypes;
import com.openinventor.ldm.nodes.SoTransferFunction;
import com.openinventor.volumeviz.nodes.SoVolumeData;
import com.openinventor.volumeviz.nodes.SoVolumeRender;

class GenericReader extends com.openinventor.ldm.readers.SoVolumeReader {
    private SbBox3f m_size;
    private SbVec3i32 m_dim;
    private int m_type;
    private int m_bytesPerVoxel;
    private int m_headerSize;
    private RandomAccessFile m_dataFile;

    public GenericReader(String fileName)
    {
        m_size = new SbBox3f(0,0,0, 10,10,10);
        m_dim =  new SbVec3i32(256,256,256);
        m_type = SoVolumeData.DataTypes.UNSIGNED_BYTE.getValue();
        m_bytesPerVoxel = 1;
        m_headerSize = 0;
        try {
            m_dataFile = new RandomAccessFile(fileName,"r");
        } catch (Exception e) {
        }
    }

    @Override
    public DataInfo getDataChar()
    {
        DataInfo dataInfo = new DataInfo();
        dataInfo.dim = m_dim;
        dataInfo.size = m_size;
        dataInfo.type = DataTypes.valueOf(m_type);
        dataInfo.readError = ReadErrors.RD_NO_ERROR;

        return dataInfo;
    }

    public SbBox3f getVolumeSize() {
        return m_size;
    }
    public SbVec3i32 getDataDimension() {
        return m_dim;
    }
    public int getDataType() {
        return m_type;
    }

    @Override
    public void getSubSlice( SbBox2i32 subSlice, int sliceNumber, SoBufferObject bufferObject) {

        long lineSize = m_dim.getX() * m_bytesPerVoxel;
        long sliceSize = m_dim.getY() * lineSize;

        long offset = m_headerSize + sliceNumber*sliceSize
                + (subSlice.getMin()).getY()*lineSize
                + (long)(subSlice.getMin()).getX()*m_bytesPerVoxel;

        int dataToRead = ((subSlice.getMax()).getX() - (subSlice.getMin()).getX() + 1)
                * m_bytesPerVoxel;

        SoCpuBufferObject cpuBufObj = new SoCpuBufferObject();
        bufferObject.map(cpuBufObj, AccessModes.SET);

        byte[] data_src = new byte[dataToRead];
        ByteBuffer data_dest = cpuBufObj.map(AccessModes.SET);
        data_dest.rewind();

        try {
            for (int i = (subSlice.getMin()).getY();
                 i <= (subSlice.getMax()).getY();
                 i++) {

                m_dataFile.seek(offset);
                m_dataFile.read(data_src);

                data_dest.put(data_src);

                offset += lineSize;
            }
        } catch (Exception e) { }
        finally {
            cpuBufObj.unmap();
            bufferObject.unmap(cpuBufObj);
        }

    }
}